package lookas;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import lookas.dao.MoviesDao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Laucher {

	public static final String BLAD = "blad";
	public static final String KATALOG = "katalog";
	final private static Logger log = LoggerFactory.getLogger(Laucher.class);

	private PlakatPreview plakat;
	private MoviesDao moviesDao;
	private String filmy;

	public void setPlakat(PlakatPreview plakat) {
		this.plakat = plakat;
	}

	public static void main(String[] args) throws Exception {
		ApplicationContext applicationContext = new FileSystemXmlApplicationContext(
				"src/main/resources/context.xml");
		Laucher laucher = (Laucher) applicationContext.getBean("Laucher");
		String line = null;
		do {
			writeln("------------------------------------------------");
			writeln("1) Informacje");
			writeln("2) Import danych");
			// writeln("3) Generuj html");
			writeln("4) Zglos blad");
			writeln("9) Wyjscie");
			write("> [1]");
			line = read();
			if ("4".equals(line))
				laucher.zglosBlad();
			else if ("3".equals(line))
				laucher.generate();
			else if ("2".equals(line))
				laucher.importData();
			else if ("9".equals(line))
				line = null;
			else
				laucher.info();
		} while (line != null);
		System.exit(0);
	}

	private void generate() {
		// TODO
	}

	private void info() {
		String line = null;
		List<Map<String, Object>> filmy = moviesDao.filmy();
		Map<String, String> film = new LinkedHashMap<String, String>();
		do {
			int i = 0;
			for (Map<String, Object> map : filmy) {
				i++;
				film.put(i + "", map.get("L").toString());
				write(String.format("%3d. ", i));
				for (String s : map.keySet()) {
					write(String.format("%-38.35s", map.get(s)));
				}
				writeln("");
			}
			writeln("------------------------------------------------");
			writeln("1) Szczegoly");
			writeln("9) Wyjscie");
			write("> [1]");
			line = read();
			if ("9".equals(line))
				line = null;
			else {
				write("nr filmu>");
				String s = read();
				String l = film.get(s);
				if (l != null)
					oFilmie(l);
			}
		} while (line != null);
	}

	private void zglosBlad() {
		boolean end = false;
		do {
			List<Map<String, Object>> filmy = moviesDao.infilmy();
			Map<String, String> film = new LinkedHashMap<String, String>();

			int i = 0;
			for (Map<String, Object> map : filmy) {
				i++;
				film.put(i + "", map.get("K").toString());
				write(String.format("%3d. ", i));
				for (String s : map.keySet()) {
					write(String.format("%-38.35s", map.get(s)));
				}
				writeln("");
			}
			writeln("------------------------------------------------");
			write("nr filmu>");
			String s = read();
			String katalog = film.get(s);
			if (katalog != null) {
				write("link IMDB>");
				s = read();
				if (s == null || !s.startsWith("http"))
					moviesDao.invalid(katalog);
				else {
					Map<String, String> map = null;
					try {
						MovieInfo movieInfo = new MovieInfo();
						map = new XmlParser().parse(movieInfo.getData(s));
						map.put(KATALOG, katalog);
					} catch (Exception e) {
						map = new LinkedHashMap<String, String>();
						map.put(KATALOG, katalog);
						map.put(BLAD, e.getMessage());
						log.info(e.getMessage());
					} finally {
						log.info(map.toString());
						moviesDao.insertORupdateData(map);
					}
				}
			} else
				end = true;
		} while (!end);
	}

	private void oFilmie(String link) {
		Map<String, Object> film = moviesDao.film(link);
		writeln(String.format("%s (%s), ocena: %s", film.get("T"), film
				.get("R"), film.get("O")));
		String op = film.get("P").toString().replaceAll("<.?p>", " ");
		int j = 0;
		for (int i = 60; i < op.length(); i += 60) {
			i = op.indexOf(" ", i);
			if (i > 0)
				writeln(op.substring(j, i));
			else
				writeln(op.substring(j));
			j = i;
		}
		writeln("------------------------------------------------");
		writeln("1) Plakat");
		String s = read();
		if ("1".equals(s))
			plakat.preview(link);
	}

	public void setFilmy(String filmy) {
		this.filmy = filmy;
	}

	public void setMoviesDao(MoviesDao moviesDao) {
		this.moviesDao = moviesDao;
	}

	private String parseKatalog(String katalog) {
		String name = katalog.toLowerCase();
		int o = name.indexOf(".pl");
		if (o >= 0)
			name = name.substring(0, o);
		o = name.indexOf("dvd");
		if (o >= 0)
			name = name.substring(0, o);
		o = name.indexOf("limited");
		if (o >= 0)
			name = name.substring(0, o);

		name = name.replaceAll("[^a-z0-9]", " ").trim().replace(' ', '+');
		return name;
	}

	private String findLink(File f) throws IOException {
		File[] fTmp = f.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.endsWith(".nfo");
			}
		});
		if (fTmp == null || fTmp.length == 0)
			return null;

		f = fTmp[0];
		try {
			BufferedReader r = new BufferedReader(new InputStreamReader(
					new FileInputStream(f)));
			String input;
			String str = "imdb.com/title/";
			while ((input = r.readLine()) != null) {
				int of = input.indexOf(str);
				if (of >= 0) {
					int eof = input.toLowerCase().replaceAll("[a-z0-9]", "+")
							.lastIndexOf("+++") + 3;
					String q = input.substring(of, eof);
					return "http://www." + q;
				}
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	private void importData() {
		Map<String, String> map = null;
		MovieInfo movieInfo = new MovieInfo();

		File f = new File(filmy);
		File[] list = f.listFiles();
		for (int i = 0; i < list.length; i++) {
			if (!list[i].isDirectory())
				continue;
			String katalog = list[i].getName();

			String link = null;
			if (moviesDao.exists(katalog)) {
				continue;
			}

			if (link == null)
				try {
					link = findLink(list[i]);
				} catch (IOException e) {
				}
			String s = parseKatalog(katalog);

			try {
				if (link == null)
					s = movieInfo.getMovieLink(s);
				else
					s = link;

				map = new XmlParser().parse(movieInfo.getData(s));
				map.put(KATALOG, katalog);
			} catch (Exception e) {
				map = new LinkedHashMap<String, String>();
				map.put(KATALOG, katalog);
				map.put(BLAD, e.getMessage());
				log.info(e.getMessage());
			} finally {
				log.info(map.toString());
				moviesDao.insertORupdateData(map);
			}
		}
	}

	public static String read() {
		BufferedReader stdin = new BufferedReader(new InputStreamReader(
				System.in));
		try {
			return stdin.readLine();
		} catch (IOException e) {
			return null;
		}
	}

	public static void write(String s) {
		BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(
				System.out));
		try {
			stdout.write(s);
			stdout.flush();
		} catch (IOException e) {
			log.warn(e.getMessage());
		}
	}

	public static void writeln(String s) {
		write(s + "\n");
	}
}
